package com.tripshare.sdk.weixin.api.util;

import com.google.common.base.Strings;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;

public class XmlConverter implements Converter {

    /**
     * 序列化
     *
     * @param value
     * @param writer
     * @param marshallingContext
     */
    @Override
    public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
        AbstractMap map = (AbstractMap) value;
        for (Object obj : map.entrySet()) {
            Map.Entry entry = (Map.Entry) obj;
            Object val = entry.getValue();
            if (null != val && !Strings.isNullOrEmpty(val.toString())) {
                writer.startNode(entry.getKey().toString());
                writer.setValue(val.toString());
                writer.endNode();
            }
        }
    }

    /**
     * 反序列化
     *
     * @param reader
     * @param unmarshallingContext
     * @return
     */
    @Override
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {

        HashMap map = new HashMap();

        recursiveMove(reader, map);

//        while (reader.hasMoreChildren()) {
//            reader.moveDown();

//            String key = reader.getNodeName(); // nodeName aka element's name
//            String value = reader.getValue();
//            map.put(key, value);


//            reader.moveUp();
//        }

        return map;
    }

    private void recursiveMove(HierarchicalStreamReader reader, HashMap resultMap) {
        while (reader.hasMoreChildren()) {
            reader.moveDown();

            String key = reader.getNodeName(); // nodeName aka element's name

            if (reader.hasMoreChildren()) {
                HashMap childrenMap = new HashMap();
                recursiveMove(reader, childrenMap);
                resultMap.put(key, childrenMap);
            } else {
                String value = reader.getValue();
                resultMap.put(key, value);
            }
            reader.moveUp();
        }
    }


    @Override
    public boolean canConvert(Class aClass) {
        return AbstractMap.class.isAssignableFrom(aClass);
    }
}
